
#include "lcd_154HSC04A.h"

void lcd_154hsc04a_reg_init(lcd_154hsc04a_t *t)
{
	t->bus->write_cmd(t->bus_handle, 0x11); // Sleep out
	hal_delay_ms(120);						// Delay 120ms

	t->bus->write_cmd(t->bus_handle, 0x36);
	t->bus->write_data8(t->bus_handle, 0xc0);

	t->bus->write_cmd(t->bus_handle, 0x3A);
	t->bus->write_data8(t->bus_handle, 0x05);

	t->bus->write_cmd(t->bus_handle, 0xB2);
	t->bus->write_data8(t->bus_handle, 0x0C);
	t->bus->write_data8(t->bus_handle, 0x0C);
	t->bus->write_data8(t->bus_handle, 0x00);
	t->bus->write_data8(t->bus_handle, 0x33);
	t->bus->write_data8(t->bus_handle, 0x33);

	t->bus->write_cmd(t->bus_handle, 0xB7);
	t->bus->write_data8(t->bus_handle, 0x35);

	t->bus->write_cmd(t->bus_handle, 0xBB);
	t->bus->write_data8(t->bus_handle, 0x32); // Vcom=1.35V

	t->bus->write_cmd(t->bus_handle, 0xC2);
	t->bus->write_data8(t->bus_handle, 0x01);

	t->bus->write_cmd(t->bus_handle, 0xC3);
	t->bus->write_data8(t->bus_handle, 0x15); // GVDD=4.8V  颜色深度

	t->bus->write_cmd(t->bus_handle, 0xC4);
	t->bus->write_data8(t->bus_handle, 0x20); // VDV, 0x20:0v

	t->bus->write_cmd(t->bus_handle, 0xC6);
	t->bus->write_data8(t->bus_handle, 0x0F); // 0x0F:60Hz

	t->bus->write_cmd(t->bus_handle, 0xD0);
	t->bus->write_data8(t->bus_handle, 0xA4);
	t->bus->write_data8(t->bus_handle, 0xA1);

	t->bus->write_cmd(t->bus_handle, 0xE0);
	t->bus->write_data8(t->bus_handle, 0xD0);
	t->bus->write_data8(t->bus_handle, 0x08);
	t->bus->write_data8(t->bus_handle, 0x0E);
	t->bus->write_data8(t->bus_handle, 0x09);
	t->bus->write_data8(t->bus_handle, 0x09);
	t->bus->write_data8(t->bus_handle, 0x05);
	t->bus->write_data8(t->bus_handle, 0x31);
	t->bus->write_data8(t->bus_handle, 0x33);
	t->bus->write_data8(t->bus_handle, 0x48);
	t->bus->write_data8(t->bus_handle, 0x17);
	t->bus->write_data8(t->bus_handle, 0x14);
	t->bus->write_data8(t->bus_handle, 0x15);
	t->bus->write_data8(t->bus_handle, 0x31);
	t->bus->write_data8(t->bus_handle, 0x34);

	t->bus->write_cmd(t->bus_handle, 0xE1);
	t->bus->write_data8(t->bus_handle, 0xD0);
	t->bus->write_data8(t->bus_handle, 0x08);
	t->bus->write_data8(t->bus_handle, 0x0E);
	t->bus->write_data8(t->bus_handle, 0x09);
	t->bus->write_data8(t->bus_handle, 0x09);
	t->bus->write_data8(t->bus_handle, 0x15);
	t->bus->write_data8(t->bus_handle, 0x31);
	t->bus->write_data8(t->bus_handle, 0x33);
	t->bus->write_data8(t->bus_handle, 0x48);
	t->bus->write_data8(t->bus_handle, 0x17);
	t->bus->write_data8(t->bus_handle, 0x14);
	t->bus->write_data8(t->bus_handle, 0x15);
	t->bus->write_data8(t->bus_handle, 0x31);
	t->bus->write_data8(t->bus_handle, 0x34);
	t->bus->write_cmd(t->bus_handle, 0x21);

	t->bus->write_cmd(t->bus_handle, 0x28);
}

void lcd_154hsc04a_rotation(lcd_154hsc04a_t *t, uint16_t angle)
{    
	t->bus->write_cmd(t->bus_handle, 0x36); //旋转命令
	switch (angle)
	{
	case 90:
		t->bus->write_data8(t->bus_handle, 0x00);
		break;
	case 180:
		t->bus->write_data8(t->bus_handle, 0x00);
		break;
	case 270:
		t->bus->write_data8(t->bus_handle, 0x00);
		break;
	case 0:
	default:
		t->bus->write_data8(t->bus_handle, 0x00);
		break;
	}
}


void lcd_154hsc04a_cmd(lcd_154hsc04a_t *t, uint8_t cmd)
{    
    t->bus->write_cmd(t->bus_handle, cmd);
}

void lcd_154hsc04a_init(lcd_154hsc04a_t *t)
{
    t->base.x_size = 240;
    t->base.y_size = 240;
    t->base.rst_time1 = 200;
    t->base.rst_time2 = 100;
    
    t->bus->reset(t->bus_handle, t->base.rst_time1, t->base.rst_time2);
    lcd_154hsc04a_reg_init(t);
    lcd_154hsc04a_rotation(t, 0);
    t->base.cmd_group.dis_on = DISPON;
    t->base.cmd_group.dis_off = DISPOFF;
    
    t->draw_complete = xSemaphoreCreateBinary();
    
    lcd_154hsc04a_clear(t, 0xffff);
}

static void lcd_154hsc04a_set_xy(lcd_154hsc04a_t *t, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{    
    t->bus->write_cmd(t->bus_handle, 0x2A); //设置列地址
    t->bus->write_data16(t->bus_handle, x0+t->x_offset);
    t->bus->write_data16(t->bus_handle, x1+t->x_offset);
    t->bus->write_cmd(t->bus_handle, 0x2B); //设置行地址
    t->bus->write_data16(t->bus_handle, y0+t->y_offset);
    t->bus->write_data16(t->bus_handle, y1+t->y_offset);
}

void lcd_154hsc04a_clear(lcd_154hsc04a_t *t, uint16_t color)
{
    uint16_t i, j;
    lcd_154hsc04a_set_xy(t,0,0,t->base.x_size-1, t->base.y_size-1);
    t->bus->write_cmd(t->bus_handle, 0x2C);
    for(i=0;i!=t->base.x_size;i++)
        for(j=0;j!=t->base.y_size;j++)
            t->bus->write_data16(t->bus_handle, color);
}

void lcd_154hsc04a_draw_rect(lcd_154hsc04a_t *t, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, const uint8_t *color_p)
{
    uint16_t i, j;
    lcd_154hsc04a_set_xy(t,x0,y0,x1,y1);
    t->bus->write_cmd(t->bus_handle, 0x2C);
    if(t->bus->write_data_dma!=NULL)
        t->bus->write_data_dma(t->bus_handle, color_p, (x1-x0+1)*(y1-y0+1));
    else {
        for(i=y0;i<=y1;i++)
        {													   	 	
            for(j=x0;j<=x1;j++)
            {
                t->bus->write_data8(t->bus_handle, *color_p++);
                t->bus->write_data8(t->bus_handle, *color_p++);
                //lcd_spi_port_write_data16(&drv->port, 0xff00);
            }
        }
        xSemaphoreGive(t->draw_complete);
    }  
}

void lcd_154hsc04a_draw_end(lcd_154hsc04a_t *t)
{
    t->bus->write_data_dma_end(t->bus_handle);
    BaseType_t xHigherPriorityTaskWoken = pdFALSE; 
    xSemaphoreGiveFromISR(t->draw_complete, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void lcd_154hsc04a_draw_complete_wait(lcd_154hsc04a_t *t)
{
    xSemaphoreTake(t->draw_complete, 2000);
}
